/*
 * PieceFactory.java
 *
 * This work is free software; you can redistribute it and/or
 * modify it under the terms of the Apache License as published 
 * by the Apache Software Foundation.
 *
 * This work is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * Apache License for more details.
 *
 * Copyright (c) 2011 Tran Hoang Anh (tranhoanganh89@gmail.com). 
 * All rights reserved.
 */
package net.hoanganh.jbraintetris;

import java.awt.Color;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Factory for creating standard Tetris piece.
 */
public class PieceFactory {

	/**
	 * Default tetris piece have 4 squares.
	 */
	private static int DEFAULT_SQUARE_NUM = 4;

	/**
	 * Used for creating random integer number.
	 */
	private static Random randomGenrator = new Random();

	/**
	 * Index of current piece, it is used to prevent randomize the same piece
	 * with previous randomization.
	 */
	private static int previousPieceIndex = -1;

	/**
	 * Static list contains all default tetris pieces. All piece instances in
	 * this list will be reuse in game.
	 */
	private static List<Piece> pieces = new ArrayList<Piece>();

	static {
		// SQUARE
		Point[] origins = new Point[DEFAULT_SQUARE_NUM];
		origins[0] = new Point(0, 0);
		origins[1] = new Point(1, 0);
		origins[2] = new Point(0, 1);
		origins[3] = new Point(1, 1);
		pieces.add(new Piece(origins, 1, Color.yellow));

		// STICK
		origins = new Point[DEFAULT_SQUARE_NUM];
		origins[0] = new Point(-1, 0);
		origins[1] = new Point(0, 0);
		origins[2] = new Point(1, 0);
		origins[3] = new Point(2, 0);
		pieces.add(new Piece(origins, 2, Color.cyan));

		// RIGHT_L
		origins = new Point[DEFAULT_SQUARE_NUM];
		origins[0] = new Point(0, -1);
		origins[1] = new Point(0, 0);
		origins[2] = new Point(0, 1);
		origins[3] = new Point(1, 1);
		pieces.add(new Piece(origins, 4, Color.orange));

		// LEFT_L
		origins = new Point[DEFAULT_SQUARE_NUM];
		origins[0] = new Point(0, -1);
		origins[1] = new Point(0, 0);
		origins[2] = new Point(-1, 1);
		origins[3] = new Point(0, 1);
		pieces.add(new Piece(origins, 4, Color.blue));

		// Z
		origins = new Point[DEFAULT_SQUARE_NUM];
		origins[0] = new Point(-1, 0);
		origins[1] = new Point(0, 0);
		origins[2] = new Point(0, 1);
		origins[3] = new Point(1, 1);
		pieces.add(new Piece(origins, 2, Color.red));

		// S
		origins = new Point[DEFAULT_SQUARE_NUM];
		origins[0] = new Point(0, 0);
		origins[1] = new Point(1, 0);
		origins[2] = new Point(-1, 1);
		origins[3] = new Point(0, 1);
		pieces.add(new Piece(origins, 2, Color.green));

		// T
		origins = new Point[DEFAULT_SQUARE_NUM];
		origins[0] = new Point(0, -1);
		origins[1] = new Point(-1, 0);
		origins[2] = new Point(0, 0);
		origins[3] = new Point(1, 0);
		pieces.add(new Piece(origins, 4, Color.pink));
	}

	/**
	 * Get random piece with random orientation.
	 * 
	 * @return a piece
	 */
	public static Piece getRandom() {
		// Get piece which not the same with previous piece
		int pieceIndex;
		do {
			pieceIndex = randomGenrator.nextInt(pieces.size());
		} while (pieceIndex == previousPieceIndex);
		previousPieceIndex = pieceIndex;
		Piece piece = pieces.get(pieceIndex);
		
		// Reset piece
		piece.reset();
		
		// Rotate random
		int rotateTimes = randomGenrator.nextInt(piece.getMaxOrientation());
		for (int i = 0; i < rotateTimes; i++) {
			piece.rotate();
		}
				
		return piece;
	}
}
